/**
react-transition-group  是一个用于实现 React 组件动画的库。它提供了一组组件，允许开发者在组件的进入、退出和状态变化时添加动画效果。
  1. 基本概念
  -  react-transition-group  允许你在组件的生命周期中添加动画效果，特别是在组件进入和退出时。
  - 该库不直接提供动画效果，而是提供了一种方式来控制动画的生命周期，开发者可以结合 CSS 或 JavaScript 动画库来实现具体的动画效果。

  2. 主要组件
  react-transition-group  提供了几个核心组件：

  -  Transition ：用于管理单个组件的进入和退出状态。
  -  CSSTransition ： Transition  的一个扩展，允许你使用 CSS 类来定义进入和退出的动画。
  -  TransitionGroup ：用于管理一组  Transition  组件，通常用于列表的动画效果。

  3. 使用示例
  1. 使用  CSSTransition  实现简单的动画：
  jsx
  import React, { useState } from 'react';
  import { CSSTransition } from 'react-transition-group';
  import './styles.css'; // 引入 CSS 动画样式

  const Example = () => {
    const [inProp, setInProp] = useState(false);

    return (
      <div>
        <button onClick={() => setInProp(!inProp)}>
          Click to Toggle
        </button>
        <CSSTransition in={inProp} timeout={300} classNames="fade">
          <div>Fade in and out</div>
        </CSSTransition>
      </div>
    );
  };
  2. CSS 动画样式：
  .fade-enter {
    opacity: 0;
  }
  .fade-enter-active {
    opacity: 1;
    transition: opacity 300ms;
  }
  .fade-exit {
    opacity: 1;
  }
  .fade-exit-active {
    opacity: 0;
    transition: opacity 300ms;
  }
  4. 主要特点
  - 易于使用：通过简单的 API，可以轻松实现复杂的动画效果。
  - 与 CSS 兼容：可以结合 CSS 动画和过渡效果，提供灵活的动画实现。
  - 支持多种动画库：可以与其他动画库（如 GSAP、Framer Motion）结合使用。

  5. 注意事项
  - 性能：在使用动画时，需注意性能，避免在动画过程中造成卡顿。
  - 动画时机：确保在适当的时机添加和移除动画类，以达到最佳效果。
  - 文档和示例：建议查看官方文档和示例，以更好地理解和利用该库的功能。

  6. 总结
  react-transition-group  是一个强大的工具，可以帮助开发者在 React 应用中实现流畅的动画效果。通过提供的组件，开发者可以轻松控制组件的进入和退出动画，结合 CSS 样式实现丰富的用户体验。
 */
import React, { PureComponent, createRef } from 'react'
import { CSSTransition, SwitchTransition, TransitionGroup } from 'react-transition-group'
import './style.css'

export default class App extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      isShow: true,
      isLogin: true,
      books: [
        { id: 111, name: "你不知道JS", price: 99 },
        { id: 222, name: "JS高级程序设计", price: 88 },
        { id: 333, name: "Vuejs高级设计", price: 77 },
      ]
    }

    this.sectionRef = createRef()
  }

  removeBook(index) {
    const newBook = [...this.state.books]
    newBook.splice(index, 1)
    this.setState({ books: newBook })
  }

  addNewBook() {
    const newBook = { id: Date.now(), name: "React高级设计", price: 66 }
    const books = [...this.state.books].concat(newBook)
    console.log(books);
    
    this.setState({ books })
  }
  
  render() {
    const { isShow, isLogin, books } = this.state
    
    return (
      <div>
        <h3>01_CSSTransition动画</h3>
        <button onClick={e => this.setState({isShow: !isShow})}>切换</button>
        {/*  
          CSSTransition组件属性:
            in: 控制动画的显示与隐藏
            classNames: 自定义类名，默认为'fade'
            timeout: 动画执行时间，默认为300ms
            appear: 是否在初次渲染时执行动画，默认为false
            unmountOnExit: 动画执行完毕后是否卸载组件，默认为false
            onEnter: 动画进入时的回调函数
            onEntering: 动画进入过程中的回调函数
            onEntered: 动画进入完成后的回调函数
            onExit: 动画退出时的回调函数
            onExiting: 动画退出过程中的回调函数
            onExited: 动画退出完成后的回调函数
            nodeRef: 指定动画元素的引用，默认为null
        */}
        <CSSTransition
          nodeRef={this.sectionRef}
          in={isShow}
          unmountOnExit={true}
          classNames="css-transition"
          timeout={2000}
          appear={true}
          onEnter={e => console.log('onEnter 开始进入动画', e)}
          onEntering={e => console.log('onEntering 进入动画中', e)}
          onEntered={e => console.log('onEntered 进入动画完成', e)}
          onExit={e => console.log('onExit 开始退出动画', e)}
          onExiting={e => console.log('onExiting 退出动画中', e)}
          onExited={e => console.log('onExited 退出动画完成', e)}
        >
          <div className='section' ref={this.sectionRef}>
            <h4>App CSSTransition</h4>
            <p>react-transition-group  是一个用于实现 React 组件动画的库。它提供了一组组件，允许开发者在组件的进入、退出和状态变化时添加动画效果</p>
          </div>
        </CSSTransition>

        {/* 
          SwitchTransition: 用于在两个组件之间切换时添加动画效果
            mode: 指定动画模式，可选值为 "out-in" 或 "in-out"，默认为 "out-in"
        */}
        <h3>02_SwitchTransition</h3>
        <SwitchTransition mode="out-in">
          <CSSTransition
            key={isLogin ? 'exit' : 'switch-transition'}
            classNames="switch-transition"
            timeout={2000}
          >
            <button onClick={e => this.setState({ isLogin: !isLogin })}>
              {isLogin ? '退出' : '登录'}
            </button>
          </CSSTransition>
        </SwitchTransition>

        {/* 
          TransitionGroup: 用于在多个组件之间添加动画效果
            component: 指定 TransitionGroup 的子组件类型，默认为 "div"
        */}
        <h3>03_TransitionGroup实现书籍列表</h3>
        <TransitionGroup component="ul">
          {
            books.map((item, index) => {
              return (
                <CSSTransition 
                  key={item.id}
                  classNames="transition-group"
                  timeout={1000}  
                >
                  <li>
                    <span>{item.name} - {item.price}</span>
                    <button onClick={e => this.removeBook(index)}>删除</button>
                  </li>
                </CSSTransition>
              )
            })
          }
        </TransitionGroup>
        <button onClick={e => this.addNewBook()}>添加新书籍</button>

      </div>
    )
  }
}
